import axios, { Method, AxiosRequestConfig } from 'axios';

interface OutData {
  [props: string]: any;
}

export default {
  _accessToken: '',

  /* 获取 */
  fetch(url: string, config: AxiosRequestConfig, outData?: OutData) {
    return this.request('get', url, config, outData);
  },

  /* 提交 */
  post(url: string, config: AxiosRequestConfig, outData?: OutData) {
    return this.request('post', url, config, outData);
  },

  /* 删除 */
  delete(url: string, config: AxiosRequestConfig, outData?: OutData) {
    return this.request('delete', url, config, outData);
  },

  /* 更新 */
  put(url: string, config: AxiosRequestConfig, outData?: OutData) {
    return this.request('put', url, config, outData);
  },

  request(
    method: Method,
    url: string,
    configData: AxiosRequestConfig,
    outData?: OutData
  ) {
    const config: AxiosRequestConfig = {
      method,
    };

    if (!url) {
      alert('缺少url');
      return;
    }

    config.url = this.parseUrl(url, configData, outData);

    if (configData.params) {
      config.params = configData.params;
    }

    if (configData.data) {
      config.params = configData.data;
    }

    configData.headers = {
      'Content-Type': 'application/json',
    };

    if (this._accessToken) {
      configData.headers['Authorization'] = `Bearer ${this._accessToken}`;
    }

    return axios
      .request(config)
      .then((res) => {
        const data = res.data as { code: boolean };
        if (data.code) {
          return data;
        } else {
          let code = res.status;
          code = code == 200 ? 0 : code;

          return {
            code,
            data,
          };
        }
      })
      .catch((err) => {
        console.log(err);
      });
  },

  /**解析url */
  parseUrl(url: string, configData: AxiosRequestConfig, outData?: OutData) {
    //替换url参数
    if (configData.params) {
      for (const key in configData.params) {
        url = url.replace(`{${key}}`, configData.params[key]);
      }
    }

    if (configData.data) {
      for (const key in configData.data) {
        url = url.replace(`{${key}}`, configData.data[key]);
      }
    }

    if (outData) {
      for (const key in outData) {
        url = url.replace(`{${key}}`, outData[key]);
      }
    }

    return url;
  },

  /** JSONP 请求 */
  jsonp<T>(url: string, timeOut?: number) {
    if (!timeOut) {
      timeOut = 3000;
    } 

    let timer: NodeJS.Timeout;

    return new Promise((resolve, reject) => {
      window.jsonCallBack = (result: T) => {
        clearTimeout(timer);
        if (JSONP.parentNode) {
          document.getElementsByTagName('head')[0].removeChild(JSONP);
        }
        resolve(result);
      };

      const JSONP = document.createElement('script');
      JSONP.type = 'text/javascript';
      JSONP.src = `${url}&callback=jsonCallBack`;

      JSONP.onerror = function () {
        clearTimeout(timer);
        if (JSONP.parentNode) {
          document.getElementsByTagName('head')[0].removeChild(JSONP);
        }
        reject('加载失败');
      };

      document.getElementsByTagName('head')[0].appendChild(JSONP);

      timer = setTimeout(() => {
        clearTimeout(timer);
        if (JSONP.parentNode) {
          document.getElementsByTagName('head')[0].removeChild(JSONP);
        }
        reject('超时');
      }, timeOut);
    });
  },
};
